// -----------------------------------------------------------------------------
// -- Copyright (c) 2009 Xilinx, Inc.
// -- This design is confidential and proprietary of Xilinx, All Rights
// Reserved.
// -----------------------------------------------------------------------------
// -   ____  ____
// -  /   /\/   /
// - /___/  \  /   Vendor: Xilinx
// - \   \   \/    Version: 1.0
// -  \   \        Filename: SDR_4TO1_16CHAN_TX.v
// -  /   /        
// - /___/   /\    Date Created: 07/14/2009 
// - \   \  /  \   
// -  \___\/\___\
// - 
// -Revision History:
// -----------------------------------------------------------------------------
/*
-------------------------------------------------------------------------------- 
Description of module:

The SDR_4TO1_16CHAN_TX module contains all components in the LVDS Transmitter,
including 16 channels of LVDS data and one channel of LVDS clock.
--------------------------------------------------------------------------------
*/

module SDR_4TO1_16CHAN_TX			
	(
	DATA_TX_P,
	DATA_TX_N,
	CLOCK_TX_P,
	CLOCK_TX_N,
	TXCLK,
	TXCLKDIV,
	DATA_TO_OSERDES,
	RESET
	);
	
input		TXCLK;			//SERIAL SIDE TX CLOCK
input		TXCLKDIV;		//PARALLEL SIDE TX CLOCK (DIVIDED FROM TXCLK)
input	[63:0]	DATA_TO_OSERDES;	//PARALLEL SIDE TX DATA
input		RESET;			//TX DOMAIN RESET

output	[15:0]	DATA_TX_P;		//SERIAL SIDE TX DATA (P)
output	[15:0]	DATA_TX_N;		//SERIAL SIDE TX DATA (N)
output		CLOCK_TX_P;		//FORWARDED CLOCK TO RX (P)
output		CLOCK_TX_N;		//FORWARDED CLOCK TO RX (N)

wire		TX_CLOCK_PREBUF;
wire	[15:0]	TX_DATA_PREBUF;

integer 	i;


//FORWARDED CLOCK					
ODDR #(
	.DDR_CLK_EDGE("OPPOSITE_EDGE"),
	.INIT(1'b0),
	.SRTYPE("ASYNC")
) ODDR_TX_CLOCK
	(
	.Q(TX_CLOCK_PREBUF), 
	.C(TXCLK), 
	.CE(1'b1), 
	.D1(1'b0), 
	.D2(1'b1), 
	.R(1'b0), 
	.S(1'b0)
	);


//FORWARDED CLOCK OUTPUT BUFFER
OBUFDS #(

	.IOSTANDARD("LVDS_25")
//    .IOSTANDARD("LVPECL_25")      // changed by DDV for test

)
OBUFDS_TX_CLOCK
	(
	.O(CLOCK_TX_P), 
	.OB(CLOCK_TX_N), 
	.I(TX_CLOCK_PREBUF)
	);


//MASTER OSERDES IN DATA PATH
OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_00 (.OQ(TX_DATA_PREBUF[00]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[000]), .D2(DATA_TO_OSERDES[016]), .D3(DATA_TO_OSERDES[032]), .D4(DATA_TO_OSERDES[048]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_01 (.OQ(TX_DATA_PREBUF[01]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[001]), .D2(DATA_TO_OSERDES[017]), .D3(DATA_TO_OSERDES[033]), .D4(DATA_TO_OSERDES[049]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_02 (.OQ(TX_DATA_PREBUF[02]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[002]), .D2(DATA_TO_OSERDES[018]), .D3(DATA_TO_OSERDES[034]), .D4(DATA_TO_OSERDES[050]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_03 (.OQ(TX_DATA_PREBUF[03]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[003]), .D2(DATA_TO_OSERDES[019]), .D3(DATA_TO_OSERDES[035]), .D4(DATA_TO_OSERDES[051]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_04 (.OQ(TX_DATA_PREBUF[04]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[004]), .D2(DATA_TO_OSERDES[020]), .D3(DATA_TO_OSERDES[036]), .D4(DATA_TO_OSERDES[052]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_05 (.OQ(TX_DATA_PREBUF[05]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[005]), .D2(DATA_TO_OSERDES[021]), .D3(DATA_TO_OSERDES[037]), .D4(DATA_TO_OSERDES[053]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_06 (.OQ(TX_DATA_PREBUF[06]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[006]), .D2(DATA_TO_OSERDES[022]), .D3(DATA_TO_OSERDES[038]), .D4(DATA_TO_OSERDES[054]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_07 (.OQ(TX_DATA_PREBUF[07]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[007]), .D2(DATA_TO_OSERDES[023]), .D3(DATA_TO_OSERDES[039]), .D4(DATA_TO_OSERDES[055]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_08 (.OQ(TX_DATA_PREBUF[08]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[008]), .D2(DATA_TO_OSERDES[024]), .D3(DATA_TO_OSERDES[040]), .D4(DATA_TO_OSERDES[056]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_09 (.OQ(TX_DATA_PREBUF[09]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[009]), .D2(DATA_TO_OSERDES[025]), .D3(DATA_TO_OSERDES[041]), .D4(DATA_TO_OSERDES[057]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_10 (.OQ(TX_DATA_PREBUF[10]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[010]), .D2(DATA_TO_OSERDES[026]), .D3(DATA_TO_OSERDES[042]), .D4(DATA_TO_OSERDES[058]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_11 (.OQ(TX_DATA_PREBUF[11]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[011]), .D2(DATA_TO_OSERDES[027]), .D3(DATA_TO_OSERDES[043]), .D4(DATA_TO_OSERDES[059]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_12 (.OQ(TX_DATA_PREBUF[12]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[012]), .D2(DATA_TO_OSERDES[028]), .D3(DATA_TO_OSERDES[044]), .D4(DATA_TO_OSERDES[060]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_13 (.OQ(TX_DATA_PREBUF[13]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[013]), .D2(DATA_TO_OSERDES[029]), .D3(DATA_TO_OSERDES[045]), .D4(DATA_TO_OSERDES[061]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_14 (.OQ(TX_DATA_PREBUF[14]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[014]), .D2(DATA_TO_OSERDES[030]), .D3(DATA_TO_OSERDES[046]), .D4(DATA_TO_OSERDES[062]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));

OSERDES #(.DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR"), .DATA_WIDTH(4), .INIT_OQ(1'b0), .INIT_TQ(1'b0), .SERDES_MODE("MASTER"), .SRVAL_OQ(1'b0), .SRVAL_TQ(1'b0), .TRISTATE_WIDTH(1)) OSERDES_TX_DATA_15 (.OQ(TX_DATA_PREBUF[15]), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(TXCLK), .CLKDIV(TXCLKDIV), .D1(DATA_TO_OSERDES[015]), .D2(DATA_TO_OSERDES[031]), .D3(DATA_TO_OSERDES[047]), .D4(DATA_TO_OSERDES[063]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(RESET), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0));


//OUTPUT BUFFERS	      // for DDV test
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_00(.O(DATA_TX_P[00]), .OB(DATA_TX_N[00]), .I(TX_DATA_PREBUF[00]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_01(.O(DATA_TX_P[01]), .OB(DATA_TX_N[01]), .I(TX_DATA_PREBUF[01]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_02(.O(DATA_TX_P[02]), .OB(DATA_TX_N[02]), .I(TX_DATA_PREBUF[02]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_03(.O(DATA_TX_P[03]), .OB(DATA_TX_N[03]), .I(TX_DATA_PREBUF[03]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_04(.O(DATA_TX_P[04]), .OB(DATA_TX_N[04]), .I(TX_DATA_PREBUF[04]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_05(.O(DATA_TX_P[05]), .OB(DATA_TX_N[05]), .I(TX_DATA_PREBUF[05]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_06(.O(DATA_TX_P[06]), .OB(DATA_TX_N[06]), .I(TX_DATA_PREBUF[06]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_07(.O(DATA_TX_P[07]), .OB(DATA_TX_N[07]), .I(TX_DATA_PREBUF[07]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_08(.O(DATA_TX_P[08]), .OB(DATA_TX_N[08]), .I(TX_DATA_PREBUF[08]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_09(.O(DATA_TX_P[09]), .OB(DATA_TX_N[09]), .I(TX_DATA_PREBUF[09]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_10(.O(DATA_TX_P[10]), .OB(DATA_TX_N[10]), .I(TX_DATA_PREBUF[10]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_11(.O(DATA_TX_P[11]), .OB(DATA_TX_N[11]), .I(TX_DATA_PREBUF[11]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_12(.O(DATA_TX_P[12]), .OB(DATA_TX_N[12]), .I(TX_DATA_PREBUF[12]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_13(.O(DATA_TX_P[13]), .OB(DATA_TX_N[13]), .I(TX_DATA_PREBUF[13]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_14(.O(DATA_TX_P[14]), .OB(DATA_TX_N[14]), .I(TX_DATA_PREBUF[14]));
OBUFDS #(.IOSTANDARD("LVDS_25")) OBUFDS_TX_DATA_15(.O(DATA_TX_P[15]), .OB(DATA_TX_N[15]), .I(TX_DATA_PREBUF[15]));


endmodule
